package com.corpgovernment.organization.service.budget;

import com.corpgovernment.api.messageadvice.enums.MsgTypeEnum;
import com.corpgovernment.api.messageadvice.soa.BasicMessageClient;
import com.corpgovernment.api.messageadvice.vo.SendMessageRequestVo;
import com.corpgovernment.api.messageadvice.vo.SendMessageResponseVo;
import com.corpgovernment.common.apollo.OrganizationApollo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.mq.enums.MessageBizTypeEnum;
import com.corpgovernment.common.utils.BigDecimalUtil;
import com.corpgovernment.common.utils.DateUtil;
import com.corpgovernment.organization.entity.db.budget.BudgetGroupEntity;
import com.corpgovernment.organization.entity.db.budget.BudgetInfoEntity;
import com.corpgovernment.organization.entity.db.budget.BudgetItemEntity;
import com.corpgovernment.organization.entity.db.budget.BudgetNotifyEntity;
import com.corpgovernment.organization.mapper.budget.BudgetGroupMapper;
import com.corpgovernment.organization.mapper.budget.BudgetInfoMapper;
import com.corpgovernment.organization.mapper.budget.BudgetItemMapper;
import com.corpgovernment.organization.mapper.budget.BudgetNotifyMapper;
import com.corpgovernment.organization.util.BudgetAlarmUtil;
import com.corpgovernment.organization.util.PreCheckUtil;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AlarmBudgetService {

    @Autowired
    private BasicMessageClient basicMessageClient;
    @Autowired
    private BudgetInfoMapper budgetInfoMapper;
    @Autowired
    private BudgetGroupMapper budgetGroupMapper;
    @Autowired
    private BudgetItemMapper budgetItemMapper;
    @Autowired
    private BudgetNotifyMapper budgetNotifyMapper;
	@Autowired
	private OrganizationApollo organizationApollo;



    /**
     * 发送短信告警阀值
     */
    public void sendAlarmMsg(String budgetId) {
        BudgetInfoEntity budgetInfo = budgetInfoMapper.selectByPrimaryKey(budgetId);
        List<BudgetGroupEntity> budgetGroups = budgetGroupMapper.selectByBudgetId(budgetId);
        List<BudgetItemEntity> budgetItems = budgetItemMapper.selectByBudgetId(budgetId);
        List<BudgetNotifyEntity> budgetNotifies = budgetNotifyMapper.selectByBudgetId(budgetId);
        String orgNames = budgetGroups.stream().map(BudgetGroupEntity::getScopeName).collect(Collectors.joining("、"));
        String budgetTime = String.format("%s-%s", DateUtil.dateToString(budgetInfo.getStartTime(), DateUtil.DF_YM_CN),
                DateUtil.dateToString(budgetInfo.getEndTime(), DateUtil.DF_YM_CN));
        String emails = budgetNotifies.stream().map(BudgetNotifyEntity::getEmail).collect(Collectors.joining(","));
        boolean result = true;
        //判断总金额
        if (!budgetInfo.getIsNotified() && BudgetAlarmUtil.isAlarm(budgetInfo.getAmount(), budgetInfo.getAmountUsed(), budgetInfo.getAmountOccupy(), budgetInfo.getWarn())) {
			String warnTotal = organizationApollo.getWarnTotal();
			String content = String.format(warnTotal, orgNames, budgetTime, BigDecimalUtil.toPlainString(budgetInfo.getAmount()),
                    BigDecimalUtil.toPlainString(BudgetAlarmUtil.calSurplus(budgetInfo.getAmount(), budgetInfo.getAmountUsed(), budgetInfo.getAmountOccupy())),
                    BigDecimalUtil.toPlainString(budgetInfo.getWarn()) + "%");
			// todo
            result = sendMessage(emails, content);
            if (result) {
                //设置告警标记，避免重复发送
                budgetInfo.setIsNotified(true);
                budgetInfoMapper.updateSelective(budgetInfo);
            }
        }
        //判断各预算项
        List<BudgetItemEntity> itemsForUpdate = Lists.newArrayList();
        for (BudgetItemEntity budgetItem : budgetItems) {
            if (!budgetItem.getIsNotified() && BudgetAlarmUtil.isAlarm(budgetItem.getAmount(), budgetItem.getAmountUsed(), budgetItem.getAmountOccupy(), budgetItem.getWarn())) {
				String warnItem = organizationApollo.getWarnItem();
				String content = String.format(warnItem, orgNames, budgetTime, budgetItem.getTypeDesc(), BigDecimalUtil.toPlainString(budgetItem.getAmount()),
                        BigDecimalUtil.toPlainString(BudgetAlarmUtil.calSurplus(budgetItem.getAmount(), budgetItem.getAmountUsed(), budgetItem.getAmountOccupy())),
                        BigDecimalUtil.toPlainString(budgetItem.getWarn()) + "%");
                result = sendMessage(emails, content);
                if (result) {
                    //设置告警标记，避免重复发送
                    budgetItem.setIsNotified(true);
                    itemsForUpdate.add(budgetItem);
                }
            }
        }
        if (!CollectionUtils.isEmpty(itemsForUpdate)) {
            budgetItemMapper.updateBatchSelective(itemsForUpdate);
        }
        PreCheckUtil.checkArgument(result, "有短信发送失败，需要重新消费");
    }

    private boolean sendMessage(String mobile, String content) {
        SendMessageRequestVo requestVo = getSendMessageRequestVo(mobile, content);
        JSONResult<SendMessageResponseVo> responseVo = basicMessageClient.sendMessage(requestVo);
        if (responseVo == null || !responseVo.isSUCCESS() || responseVo.getData() == null) {
            log.info(String.format("调用发送短信接口失败[%s]", mobile));
            return false;
        }
        if (!responseVo.getData().getFlag()) {
            log.info(String.format("发送阀值告警短信失败[%s][%s]", mobile, responseVo.getData().getErrMsg()));
            return false;
        }
        return true;
    }

    private SendMessageRequestVo getSendMessageRequestVo(String mobile, String content) {
        SendMessageRequestVo requestVo = new SendMessageRequestVo();
        requestVo.setMsgTypeEnum(MsgTypeEnum.NORMAL);
        requestVo.setBizEnum(MessageBizTypeEnum.BUDGET_NOTIFY);
        requestVo.setMobile(mobile);
        requestVo.setContent(content);
        return requestVo;
    }
}